// log.cpp
// Copyright (C) 2008 Sam Bateman
// samuel.bateman@gmail.com
//
// This file is part of DVD On Fire.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

//! @file log.cpp
//! @author Sam Bateman
//! @brief Source file for the Log class.

#include <cstdio>
#include <ctime>
#include <stdexcept>
#include <string>
#include "log.h"
using namespace std;

namespace dvdonfire
{
    namespace lib
    {
        // struct Log::Impl {{{
        struct Log::Impl
        {
            FILE *fp;
        };
        // }}}
        // Log::Log(dir) {{{
        //! @brief Constructor.
        //! @param dir Directory to log to.
        Log::Log(const std::string& dir)
        {
            // get the date and time
            time_t unix_time = time(NULL);
            tm *real_time = localtime(&unix_time);
            char filename[100];
            sprintf(filename, "doflog_%04d%02d%02d_%02d%02d%02d.log",
                    real_time->tm_year + 1900,
                    real_time->tm_mon + 1,
                    real_time->tm_mday,
                    real_time->tm_hour,
                    real_time->tm_min,
                    real_time->tm_sec);
            string file = dir + filename;

            // open the log file
            impl = new Impl;
            impl->fp = fopen(file.c_str(), "w");
            if (!impl->fp) throw runtime_error("Error opening file " + file);
        }
        // }}}
        // Log::~Log() {{{
        //! @brief Destructor.
        Log::~Log()
        {
            fclose(impl->fp);
            delete impl;
        }
        // }}}
        // Log::log(who, message, severity) {{{
        //! @brief Logs a message to file.
        //! @param who Where the message originates.
        //! @param message Message to log.
        //! @param severity Severity of the message.
        //!
        //! Writes a message to the open log file with the appropriate prefix
        //! indicating origin and severity.
        void Log::log(const std::string& who, const std::string& message,
                      Level severity)
        {
            static const char *level_strs[] = {
                "DEBUG",
                "INFO",
                "WARNING",
                "ERROR"
            };
            fprintf(impl->fp, "%s: %s: %s\n",
                    level_strs[severity],
                    who.c_str(),
                    message.c_str());
            fflush(impl->fp);
        }
        // }}}
    }
}
